﻿@{
    Layout = null;
    string stockInTypeListJson = System.Text.Json.JsonSerializer.Serialize(
        ViewBag.StockInTypeList ?? new List<Model.WmsDictData>(),
        new System.Text.Json.JsonSerializerOptions
        {
            ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles,
            Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
        }
    );
    string stockInOrderStatusList = System.Text.Json.JsonSerializer.Serialize(
        ViewBag.StockInOrderStatusList ?? new List<Model.WmsDictData>(),
        new System.Text.Json.JsonSerializerOptions
        {
            ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles,
            Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
        }
    );
}

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8" />
    <title>新增订单</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <link rel="stylesheet" href="//unpkg.com/element-plus/dist/index.css" />
    <script src="//unpkg.com/element-plus"></script>
    <script src="https://unpkg.com/element-plus/dist/locale/zh-cn.min.js"></script>
    <style>
        .basicInfo {
            width: 82%;
            height: 600px;
            background-color: #fff;
            padding-top: 20px;
            margin-top: 30px;
            margin-left: 20px;
            box-shadow: 0 0 10px 4px rgba(0, 0, 0, 0.1);
        }

        .stockUpDetail {
            width: 82%;
            min-height: 530px;
            background-color: #fff;
            padding-top: 10px;
            margin-left: 20px;
            margin-top: 50px;
            box-shadow: 0 0 10px 4px rgba(0, 0, 0, 0.1);
        }

        .uploadAttachment {
            width: 82%;
            min-height: 450px;
            background-color: #fff;
            padding-top: 10px;
            margin-left: 20px;
            margin-top: 50px;
            box-shadow: 0 0 10px 4px rgba(0, 0, 0, 0.1);
        }

        .saveBlock {
            display: grid;
            place-items: center;
            position: sticky;
            bottom: 0;
            width: 100%;
            height: 60px;
            background-color: #fff;
            z-index: 20;
            box-shadow: 0 0 10px 4px rgba(0, 0, 0, 0.1);
        }

        .titleH {
            margin-left: 40px;
        }

        .orderTable {
            margin: 0 auto;
            width: 80%;
            border-spacing: 0 40px;
        }

        .imp {
            color: red;
        }

        .orderTable tbody tr td {
            border-spacing: 0 20px;
        }

        .custom-readonly-input .el-input__inner {
            background-color: #f0f0f0 !important;
            padding: 0px;
        }

        .custom-readonly-input .el-input__wrapper {
            background-color: #f0f0f0 !important;
        }

        /* 树控件样式优化 */
        .el-tree {
            border: 1px solid #e5e7eb;
            border-radius: 4px;
            padding: 10px;
            max-height: 400px;
            overflow-y: auto;
        }

        .tree-title {
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid #eee;
        }

        .detailBlock {
            padding-left: 30px;
        }

        .uploadAttach {
            padding-top: 30px;
            padding-left: 60px;
        }

        .searchBlock {
            display: inline;
        }

        .buttonBlock {
            display: inline;
            margin-left: 50%;
        }

        /* 合计行样式优化 */
        .el-table__footer-wrapper {
            font-weight: bold;
            background-color: #f5f7fa;
        }

            .el-table__footer-wrapper td {
                text-align: center !important;
            }

        .promptWord {
            color: #606266;
        }

        .upload-demo {
            display: inline-block;
        }

        .btnBlock {
            margin-left: auto;
            padding: 10px 20px 10px 10px;
        }

        .pagination-container {
            margin-left: 45%;
        }

        .valueV {
            color: orangered;
            font-weight: bolder;
        }

        .mainBlock {
            font-size: 16px;
            display: flex;
            justify-content: center;
        }

        .usersBlock .selected {
            background-color: #E3F5ED;
            cursor: pointer;
        }

        .tree-title {
            font-size: 16px;
            font-weight: bold;
        }

        .el-tree-node.is-current > .el-tree-node__content {
            background-color: #E3F5ED !important; /* 替换为你的目标颜色 */
        }

        .el-tree-node__content {
            padding: 12px 16px;
        }

        .orderTitleContent {
            color: red;
            font-weight: bold;
        }
    </style>
    <style scoped>

    </style>
</head>
<body>
    <div id="app" class="common-layout"
         data-stock-in-type-list="@stockInTypeListJson"
         data-stock-in-order-status-list="@stockInOrderStatusList">
        <div class="basicInfo">
            <h2 class="titleH">基础信息</h2>
            <hr />
            <div class="basicInfoForm">
                <table class="orderTable">
                    <tbody>
                        <!-- 第一行：调拨单号（未定义变量设为''）、调拨类型（已定义保留） -->
                        <tr>
                            <td>
                                <span class="imp">*</span>&nbsp;&nbsp;&nbsp;调拨单号
                            </td>
                            <td>
                                <el-input type="text"
                                          v-model="transferOrderNo"
                                          style="width:80%;"
                                          readonly
                                          placeholder="自动获取系统编号">
                                </el-input>
                            </td>
                            <td>
                                <span class="imp">*</span>&nbsp;&nbsp;&nbsp;调拨类型
                            </td>
                            <td>
                                <el-select placeholder="请选择"
                                           style="width:80%;"
                                           v-model="selectedStockType">
                                    <el-option v-for="(type, index) in stockInTypeList"
                                               :key="index"
                                               :label="type.Name"
                                               :value="type.Code">
                                    </el-option>
                                </el-select>
                            </td>
                        </tr>

                        <!-- 第二行：调拨日期（未定义变量设为''）、调出仓库（未定义变量设为空数组） -->
                        <tr>
                            <td>
                                <span class="imp">*</span>&nbsp;&nbsp;&nbsp;调拨申请日期
                            </td>
                            <td>
                                <el-date-picker type="date"
                                                placeholder="请选择日期"
                                                style="width:80%;"
                                                v-model="purchaseDate"
                                                value-format="YYYY-MM-DD"
                                                v-on:change="handleDateChange">
                                </el-date-picker>
                            </td>
                            <td>
                                <span class="imp">*</span>&nbsp;&nbsp;&nbsp;调出仓库
                            </td>
                            <td>
                                <el-select placeholder="请选择出库仓库"
                                           style="width:80%;"
                                           v-model="outWarehouseId"
                                    v-on:change="checkWarehouseSame"
                                    v-if="warehouseList.length > 0">
                                    <el-option
                                        v-for="warehouse in warehouseList"
                                        :key="warehouse.wareHouseId"
                                        :label="warehouse.warehouseName"
                                        :value="Number(warehouse.wareHouseId)">
                                    </el-option>
                                </el-select>
                                <el-button style="border:0px;color:limegreen">设置</el-button>
                            </td>
                        </tr>

                        <!-- 第三行：调入仓库（同调出仓库，未定义变量设为空数组）、经办人（已定义保留） -->
                        <tr>
                            <td>
                                <span class="imp">*</span>&nbsp;&nbsp;&nbsp;调入仓库
                            </td>
                            <td>
                                <el-select placeholder="请选择入库仓库"
                                           style="width:80%;"
                                           v-model="inWarehouseId"
                                    v-on:change="checkWarehouseSame"
                                    v-if="warehouseList.length > 0">
                                    <el-option
                                        v-for="warehouse in warehouseList"
                                        :key="warehouse.wareHouseId"
                                        :label="warehouse.warehouseName"
                                        :value="Number(warehouse.wareHouseId)">
                                    </el-option>
                                </el-select>
                                <el-button style="border:0px;color:limegreen">设置</el-button>
                            </td>
                            <td>
                                <span class="imp">*</span>&nbsp;&nbsp;&nbsp;经办人
                            </td>
                            <td>
                                <el-input placeholder="请选择"
                                          v-model="operatorName"
                                          style="width:80%;"
                                          v-on:click="selectOperatorModel=true"
                                          readonly>
                                </el-input>
                            </td>
                        </tr>

                        <!-- 第四行：备注（未定义变量设为''） -->
                        <tr>
                            <td>
                                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;备注
                            </td>
                            <td colspan="3">
                                <el-input placeholder="请输入"
                                          v-model="remark"
                                          style="width:100%;"
                                          type="textarea"
                                          rows="7"
                                          readonly>
                                </el-input>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <div class="stockUpDetail">
            <h2 class="titleH">调拨明细</h2>
            <hr />
            <div class="detailBlock">
                <div class="addAndRemove">
                    <!-- 打开添货弹窗（已定义保留）、移除（未定义设为空函数） -->
                    <div class="addAndRemove">
                        <el-button type="success"
                                   v-on:click="handleAddGoods">
                            添加
                        </el-button>&nbsp;&nbsp;&nbsp;
                        <el-button type="danger" v-on:click="removeGoodsDetail">移除</el-button>
                    </div>
                </div>
                <div class="detailTable">
                    <!-- 货品明细表格（未定义变量设为空数组，未定义函数设为空函数） -->
                    <el-table :data="goodsDetailData" 
                                style="width: 100%; margin-top: 10px;" 
                                ref="goodsTableRef" 
                                :row-key="(row) => row.id" 
                                v-on:select-all ="handleDetailSelectAll"
                                v-on:selection-change ="handleDetailSelectionChange"
                                stripe>
                        <el-table-column type="selection" width="50"></el-table-column>
                        <el-table-column label="序号" width="70">
                            <template #default="scope">
                                {{ scope.$index + 1 }}
                            </template>
                        </el-table-column>
                        <el-table-column prop="goodsName" label="货品名称" width="150"></el-table-column>
                        <el-table-column prop="goodsCode" label="货品编号" width="150"></el-table-column>
                        <el-table-column prop="specification" label="规格型号" width="120"></el-table-column>
                        <el-table-column label="单位" width="80">吨</el-table-column>
                        <el-table-column prop="goodsTypeName" label="货品类型" width="120"></el-table-column>
                        <el-table-column prop="inStock" label="调入仓库当前库存" width="150"></el-table-column>
                        
                        <el-table-column prop="inLocationId" label="调入仓库库位" width="130">
                            <template #default="scope">
                                <el-select v-model="scope.row.inLocationId"
                                    placeholder="请选择"
                                    style="width: 100%"
                                    :disabled="!inWarehouseId || inLocationList.length === 0"
                                    v-on:click="handleInLocationClick"
                                >
                                    <el-option
                                        v-for="(item, index) in inLocationList"
                                        :key="item.storageLocationId"
                                        :label="item.storageLocationName"
                                        :value="item.storageLocationId"  
                                    ></el-option>
                                </el-select>
                            </template>
                        </el-table-column>
                        <el-table-column prop="outStock" label="调出仓库当前库存" width="150"></el-table-column>
                        <el-table-column prop="outLocationId" label="调出仓库库位" width="130">
                            <template #default="scope">
                                <el-select v-model="scope.row.outLocationId"
                                           placeholder="请选择"
                                           style="width: 100%"
                                           :disabled="!outWarehouseId || outLocationList.length === 0"
                                           v-on:change ="handleOutLocationChange(scope.row)">
                                    <el-option v-for="(item, index) in outLocationList"
                                               :key="item.storageLocationId"
                                               :label="item.storageLocationName"
                                               :value="item.storageLocationId"></el-option>
                                </el-select>
                            </template>
                        </el-table-column>
                        <el-table-column prop="outLocationAqty" label="调出仓库位当前库存" width="150"></el-table-column>
                        <el-table-column prop="transferQty" label="调拨数量" width="130">
                            <template #default="scope">
                                <el-input v-model.number="scope.row.transferQty"
                                          type="number"
                                          min="1"
                                          v-on:input ="handleQtyChange(scope.row)"
                                          style="width: 80px;"></el-input>
                            </template>
                        </el-table-column>
                        <el-table-column prop="purchaseReferencePrice" label="入库单价(元)" width="120" :formatter="formatNumber"></el-table-column>
                        <el-table-column prop="transferAmount" label="调拨金额(元)" width="120" :formatter="formatNumber"></el-table-column>
                        <el-table-column prop="remark" label="备注" width="200">
                            <template #default="scope">
                                <el-input type="textarea" v-model="scope.row.remark" placeholder="请输入备注" :rows="3" style="width: 100%"></el-input>
                            </template>
                        </el-table-column>
                        <el-table-column fixed="right" label="操作" min-width="100">
                            <template #default="scope">
                                <el-button link type="danger" v-on:click ="removeDetail(scope.row)">移除</el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                    <!-- 合计行（未定义变量设为''） -->
                    <div class="fixed-full-row" style="
                                                    border-bottom:1px solid #f0f0f0;
                                                    height:28px;
                                                    padding: 10px;
                                                    display: flex;
                                                    justify-content: space-between;
                                                    align-items: center;">
                        <span class="promptWord" style="padding-left: 30px;">合计</span>
                        <div class="countNum" style="display:inline-block;">
                            <span class="promptWord">调拨种类: <span class="valueV">{{ totalCategories }}</span></span>&nbsp;&nbsp;&nbsp;&nbsp;
                            <span class="promptWord">调拨数量(吨): <span class="valueV">{{ totalTransferQty }}</span></span>&nbsp;&nbsp;&nbsp;&nbsp;
                            <span class="promptWord">调拨金额: <span class="valueV">{{ totalTransferAmount }}</span></span>&nbsp;&nbsp;&nbsp;&nbsp;
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="uploadAttachment">
            <h2 class="titleH">上传附件</h2>
            <hr />
            <div class="uploadAttach">
                <!-- 上传附件（已定义保留） -->
                <el-upload class="upload-demo"
                           action="/WhInbound/UploadAttachment"
                           name="file"
                           :file-list="tempFileList"
                           :show-file-list="false"
                           accept=".doc,.docx,.pdf,.rar,.zip"
                           :limit="10"
                           :on-exceed="handleFileExceed"
                           :on-success="handleUploadSuccess"
                           :on-remove="handleFileRemove">
                    <el-button type="primary">选择文件</el-button>
                </el-upload>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                <span class="promptWord">支持格式：doc,docx,pdf,rar,zip | 单个文件≤200MB | 最多10个文件</span>

                <!-- 附件列表（已定义保留） -->
                <div class="attachmentFile" style="margin-top: 20px;">
                    <div v-for="(file, index) in tempFileList"
                         :key="file.uid"
                         class="file-item"
                         style="width:60%;display: flex; align-items: center; margin: 10px 0; padding: 8px; border: 1px solid #eee; border-radius: 4px;">
                        <span style="flex: 1;">{{ file.name }}</span>
                        <el-button size="small"
                                   type="text"
                                   style="color: #ff4d4f;"
                                   v-on:click="removeTempFile(index)">
                            删除
                        </el-button>
                    </div>
                </div>
            </div>
        </div>
        <div class="saveBlock">
            <div class="btnBlock">
                <el-button v-on:click="closeDetail">关闭</el-button>
                    &nbsp;&nbsp;&nbsp;&nbsp;<el-button v-on:click="saveAsDraft">保存草稿</el-button>
                &nbsp;&nbsp;&nbsp;&nbsp;<el-button type="success" :disabled="isSaveBtnDisabled" v-on:click="saveThis">保存</el-button>
            </div>
        </div>
        <!-- 选择经办人模态框（已定义保留，仅修正未定义的El-icon引用） -->
        <el-dialog v-model="selectOperatorModel" :width="1000" :modal="false">
            <h3>选择人员</h3>
            <hr />
            <br />
            <div class="mainBlock" style="border:1px solid #aaa">
                <!-- 左侧：机构选择树 -->
                <div class="organazationBlock" style="width:350px;border-right:1px solid #aaa;display:inline-block;padding:10px;">
                    <div class="tree-title" style="margin:10px">机构选择</div>
                    <el-tree :data="filterDepartTree"
                             :props="{ label: 'name', value: 'id', children: 'children' }"
                             v-on:node-click="handleOrgSelect"
                             highlight-current
                             current-node-class="org-tree-selected" />
                </div>
                <!-- 中间：人员列表 -->
                <div class="usersBlock" style="width:300px;border-right:1px solid #aaa;display:inline-block;padding:10px;">
                    <div class="tree-title" style="margin:10px">人员选择</div>
                    <el-scrollbar style="height: 400px;">
                        <ul style="list-style: none;padding-left: 0;margin: 0;">
                            <li v-for="user in filteredUsers"
                                :key="user.id"
                                v-on:click="handleUserSelect(user)"
                                :class="{ 'selected': selectedUsers.some(item => item.id === user.id) }"
                                style="list-style-type: none;padding:10px">
                                {{ user.name }}
                            </li>
                        </ul>
                    </el-scrollbar>
                </div>
                <!-- 右侧：已选择人员展示（替换未定义的El-icon为文字按钮） -->
                <div class="selectedUser" style="width:300px;display:inline-block;padding:10px;">
                    <div class="tree-title" style="margin:10px">已选择</div>
                    <div v-if="selectedUsers.length === 0" style="margin:10px">暂无选择</div>
                    <div v-else>
                        <div v-for="(user, index) in selectedUsers"
                             :key="user.id"
                             style="display: flex; align-items: center; justify-content: space-between;">
                            <span style="padding:10px;background-color:#E3F5ED;width:100%">{{ user.name }}</span>
                            <!-- 替换El-icon为文字按钮，避免图标未定义报错 -->
                            <el-button size="mini" type="text" style="color:#ff4d4f" v-on:click="removeSelectedUser(index)">删除</el-button>
                        </div>
                    </div>
                </div>
            </div>
            <template #footer>
                <div class="dialog-footer">
                    <el-button v-on:click="selectOperatorModel = false">取消</el-button>
                    <el-button type="primary" v-on:click="confirmOperatorSelect">确定</el-button>
                </div>
            </template>
        </el-dialog>

        @* 调拨添加货品模态框 *@
        <el-dialog v-model="addGoodsDialog" title="添加货品" :width="1000" :modal="false">
            <!-- 搜索区域 -->
            @* <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
                <el-input v-model="goodsSearchKey"
                          placeholder="请输入货品编号/名称"
                          clearable
                          v-on:keyup.enter="searchGoods"
                          style="width: 300px; margin-right: 10px;"
                ></el-input>
                <div style="display: flex; gap: 10px;">
                    <el-button type="primary" v-on:click="searchGoods">查询</el-button>
                    <el-button v-on:click="resetGoodsSearch">重置</el-button>
                </div>
            </div> *@

            <!-- 货品表格 -->
            <el-table :data="paginatedGoodsData"
                      style="width: 100%; margin-top: 10px"
                      ref="goodsTable"
                      stripe
                      v-on:selection-change="handleGoodsSelectionChange">
                <el-table-column type="selection" width="50"></el-table-column>
                <el-table-column label="序号" width="70">
                    <template #default="scope">
                        {{ (goodsCurrentPage - 1) * goodsPageSize + scope.$index + 1 }}
                    </template>
                </el-table-column>
                <el-table-column prop="goodsCode" label="货品编号" width="150"></el-table-column>
                <el-table-column prop="goodsName" label="货品名称" width="150"></el-table-column>
                <el-table-column prop="specification" label="规格型号" width="120"></el-table-column>
                <el-table-column label="单位" width="80">吨</el-table-column>
                <el-table-column prop="purchaseReferencePrice" label="入库单价(元)" width="120" :formatter="formatNumber"></el-table-column>
                <el-table-column prop="outStock" label="调出仓库库存" width="150" :formatter="formatNumber"></el-table-column>
            </el-table>

            <!-- 分页 -->
            <div style="margin-top: 10px; text-align: right;">
                <el-pagination v-model:current-page="goodsCurrentPage"
                               v-model:page-size="goodsPageSize"
                               :page-sizes="[10, 20, 50, 100]"
                               :total="goodsTotal"
                               layout="total, sizes, prev, pager, next, jumper"
                               v-on:size-change ="handleGoodsPageSizeChange"
                               v-on:current-change="handleGoodsPageChange"></el-pagination>
            </div>

            <!-- 弹窗底部按钮 -->
            <template #footer>
                <div class="dialog-footer">
                    <el-button v-on:click="addGoodsDialog = false">取消</el-button>
                    <el-button type="primary" v-on:click="confirmAddGoods">确定</el-button>
                </div>
            </template>
        </el-dialog>
    </div>
    <script>
        const { createApp, ref, onMounted, reactive, watch, nextTick } = Vue;
        const { ElMessageBox, ElMessage } = ElementPlus;
        const app = createApp({
            setup() {
                // -------------------------- 1. 已定义保留的核心变量 --------------------------
                const goodsTableRef = ref(null);
                // 数据字典
                const stockInTypeList = ref([]);
                const selectedStockType = ref('');
                // 经办人选择
                const selectOperatorModel = ref(false);
                const operatorName = ref('');
                const filterDepartTree = ref([]);
                const filterAllManData = ref([]);
                const selectedOrgId = ref('');
                const filteredUsers = ref([]);
                const selectedUsers = ref([]);
                // 上传附件
                const tempFileList = ref([]);
                //按钮禁用
                const isSaveBtnDisabled = ref(false);

                // -------------------------- 2. 未定义变量设为''或空数组 --------------------------
                const transferOrderNo = ref(''); // 调拨单号
                const purchaseDate = ref(''); // 调拨日期
                const warehouseList = ref([]); // 仓库列表
                const selectedWarehouseId = ref(''); // 选中仓库ID
                const remark = ref(''); // 备注
                const nonPurchaseQuantity = ref(''); // 调拨数量合计
                const receivedQuantity = ref(''); // 调入库存合计
    
                // -------------------------- 3. 已定义保留的核心方法 --------------------------
                const getCurrentUserId = () => {
                    // 1. 从 sessionStorage 读取存储的 user JSON 字符串
                    const userStr = sessionStorage.getItem('YH');
                    if (!userStr) {
                        ElMessage.warning('未检测到登录状态，请重新登录');
                        return '';
                    }

                    try {
                        // 2. 解析 JSON 字符串为对象
                        const userObj = JSON.parse(userStr);
                        // 3. 提取 usersId（兼容可能的空值）
                        const userId = userObj?.id?.toString() || '';

                        if (!userId) {
                            ElMessage.warning('用户信息不完整，请重新登录');
                        }
                        return userId;
                    } catch (error) {
                        // 处理 JSON 解析失败的异常（如格式错误）
                        console.error('解析用户信息失败：', error);
                        ElMessage.error('用户信息异常，请重新登录');
                        return '';
                    }
                };

                //当前登录用户Id
                const currentUserId = ref(getCurrentUserId());


                // 数据字典初始化
                const initDictData = () => {
                    try {
                        let stockInTypeStr = document.getElementById('app').dataset.stockInTypeList || '[]';
                        stockInTypeStr = decodeURIComponent(stockInTypeStr);
                        const stockInTypeData = JSON.parse(stockInTypeStr);
                        stockInTypeList.value = Array.isArray(stockInTypeData) ? stockInTypeData : [];
                    } catch (e) {
                        console.error('字典解析异常:', e);
                        ElMessage.error('数据字典加载失败');
                    }
                };
                // 部门树加载
                const loadFilterDepartments = async () => {
                    try {
                        const res = await axios.get('/StockUpOrder/GetOrgInfoForSelectTable');
                        console.log('后端返回的原始部门数据：', res.data);
                        const formatTree = (nodes) => nodes.map(node => ({
                            id: String(node.id), // 根据实际返回，用 node.id 即可，若有 orgId 再考虑兼容
                            name: node.label || '未命名部门', // 关键修改：用 node.label 作为部门名称
                            children: node.children && node.children.length ? formatTree(node.children) : []
                        }));
                        filterDepartTree.value = formatTree(res.data || []);
                    } catch (err) {
                        ElMessage.error('部门数据加载失败');
                    }
                };
                // 人员加载
                const loadFilterPersons = async () => {
                    try {
                        const res = await axios.get('/StockUpOrder/GetUserInfoForSelectTable');
                        filterAllManData.value = res.data ? res.data.map(person => ({
                            id: String(person.usersId),
                            name: person.usersTrueName || '未知人员',
                            orgId: String(person.orgId)
                        })) : [];
                    } catch (err) {
                        ElMessage.error('人员数据加载失败');
                    }
                };
                // 部门递归筛选
                const getDeptIdsRecursive = (dept) => {
                    const ids = [dept.id];
                    if (dept.children && dept.children.length) {
                        dept.children.forEach(child => ids.push(...getDeptIdsRecursive(child)));
                    }
                    return ids;
                };
                // 机构选择
                const handleOrgSelect = (node) => {
                    selectedOrgId.value = node.id;
                    const deptIds = getDeptIdsRecursive(node);
                    filteredUsers.value = filterAllManData.value.filter(person =>
                        deptIds.includes(String(person.orgId))
                    );
                };
                // 人员选择
                const handleUserSelect = (user) => {
                  selectedUsers.value = [user]; // 直接覆盖，只保留当前选的人员
                };
                // 人员删除
                const removeSelectedUser = (index) => {
                    selectedUsers.value.splice(index, 1);
                };
                // 经办人确认
                const confirmOperatorSelect = () => {
                    operatorName.value = selectedUsers.value.map(user => user.name).join(',');
                    selectOperatorModel.value = false;
                };
                
                // 附件超出限制
                const handleFileExceed = (files, uploadFiles) => {
                    ElMessage.warning(`最多选择10个文件，当前已选${uploadFiles.length + files.length}个`);
                };
                // 附件上传成功
                const handleUploadSuccess = (response, uploadFile) => {
                    if (response.success) {
                        // 1. 前端生成固定唯一的附件ID（用GUID，确保全局唯一，格式："att-" + 随机GUID）
                        const uniqueFileId = `att-${self.crypto.randomUUID()}`;

                        // 2. 查找当前文件在列表中的索引，无则新增
                        const index = tempFileList.value.findIndex(item => item.uid === uploadFile.uid);
                        if (index > -1) {
                            // 覆盖现有文件的fileId（用前端生成的唯一ID），并保存后端返回的文件路径
                            tempFileList.value[index] = {
                                ...tempFileList.value[index],
                                fileId: uniqueFileId, // 前端固定唯一ID
                                serverFilePath: response.data.savePath // 后端文件保存路径（用于回滚删除）
                            };
                        } else {
                            // 新增文件到列表，携带前端唯一ID和后端路径
                            tempFileList.value.push({
                                ...uploadFile,
                                fileId: uniqueFileId, // 前端固定唯一ID
                                serverFilePath: response.data.savePath // 后端文件保存路径
                            });
                        }
                        ElMessage.success('附件上传成功');
                    } else {
                        ElMessage.error(response.message);
                    }
                };
                // 附件删除
                const removeTempFile = async (index) => {
                    const file = tempFileList.value[index];
                    // 1. 若未上传成功（无 fileId），直接删除前端列表项
                    if (!file.fileId) {
                        tempFileList.value.splice(index, 1);
                        return;
                    }

                    try {
                        // 2. 调用后端 DeleteAttachment 接口，传递 fileId（JSON 格式）
                        const response = await axios.post(
                            '/WhTransfer/DeleteAttachment',  // 控制器接口地址（注意：是 WhTransfer 而非 WhInbound）
                            { FileId: file.fileId },         // 符合后端 DeleteAttachmentRequest 类的参数格式
                            {
                                headers: {
                                    'Content-Type': 'application/json'  // 明确指定 JSON 格式
                                }
                            }
                        );

                        // 3. 接口调用成功，删除前端列表项
                        if (response.data.success) {
                            tempFileList.value.splice(index, 1);
                            ElMessage.success('附件删除成功');
                        } else {
                            // 4. 接口调用失败，提示用户
                            ElMessage.error(`附件删除失败：${response.data.message || '服务器异常'}`);
                        }
                    } catch (error) {
                        // 5. 捕获网络异常
                        console.error('附件删除接口调用失败：', error);
                        ElMessage.error('网络异常，附件删除失败，请重试');
                    }
                };
                // 附件移除（上传组件回调）
                const handleFileRemove = async (uploadFile) => {
                    if (uploadFile.fileId) {
                        try {
                            await axios.post(
                                '/WhTransfer/DeleteAttachment',
                                { FileId: uploadFile.fileId },
                                { headers: { 'Content-Type': 'application/json' } }
                            );
                            // 无需额外删除前端列表，组件会自动更新 tempFileList
                        } catch (error) {
                            console.error('上传组件移除附件时调用接口失败：', error);
                            ElMessage.error('已上传附件移除失败，请手动删除');
                        }
                    }
                };
                // 获取调拨单号
                const getTransferOrder = ()=>{
                    axios.post('/NumberingRules/GenerateByRuleId?ruleId=5')
                    .then(res=>{
                        transferOrderNo.value = res.data.number;
                    })
                }

                // 新增：表头全选事件处理（选中/取消选中所有行）
                const handleDetailSelectAll = (isSelected) => {
                    // 1. 校验表格实例是否存在
                    if (!goodsTableRef.value) return;

                    // 2. 遍历所有行数据，调用 toggleRowSelection 实现全选/取消
                    goodsDetailData.value.forEach(row => {
                        goodsTableRef.value.toggleRowSelection(row, isSelected);
                    });

                    // 3. 同步更新 selectedGoods（用于后续批量移除等操作）
                    selectedGoods.value = isSelected ? [...goodsDetailData.value] : [];
                };
                const handleDetailSelectionChange = (selectedRows) => {
                  selectedGoods.value = selectedRows; // 直接将选中的行赋值给 selectedGoods
                };

                //-----------------------------------仓库----------------------------------------------
                const inWarehouseId = ref('');  // 入库仓库
                const outWarehouseId = ref(''); // 出库仓库
                const loadWarehouseList = async () => {
                    try {
                        const res = await axios.get('/WhInbound/GetWareHouseInfoForSelect');
                        warehouseList.value = res.data && Array.isArray(res.data) ? res.data : [];
                        console.log("仓库列表", warehouseList.value);
                        if (warehouseList.value.length === 0) ElMessage.info('未查询到仓库数据');
                    } catch (error) {
                        console.error('加载仓库列表失败：', error); // 捕获请求异常
                        ElMessage.error('仓库数据加载失败，请重试');
                        warehouseList.value = []; // 异常时清空数据源，避免下拉框渲染错误
                    }
                };

                const handleAddGoods = () => {
                    if (!inWarehouseId.value) {
                        ElMessage.warning('请选择入库仓库！');
                        return;
                    }
                    if (!outWarehouseId.value) {
                        ElMessage.warning('请选择出库仓库！');
                        return;
                    }
                    openAddGoodsDialog();
                };

                // 3. 同仓校验逻辑
                const checkWarehouseSame = () => {
                    if (inWarehouseId.value && outWarehouseId.value) {
                        if (inWarehouseId.value === outWarehouseId.value) {
                            ElMessage.warning('入库仓库和出库仓库不能为同一仓库！');
                            // 可选：清空仓库选择
                            inWarehouseId.value = '';
                            outWarehouseId.value = '';
                        }
                    }
                };
                //-----------------------------------仓库结束------------------------------------------

                //-----------------------------------调拨明细开始--------------------------------------
                // 添货弹窗打开
                const openAddGoodsDialog = () => {
                    addGoodsDialog.value = true;
                    goodsSearchKey.value = '';
                    loadGoodsData(outWarehouseId.value, inWarehouseId.value);
                    handleGoodsPageChange(1); // 初始化分页

                };
                        // 弹窗相关
                const addGoodsDialog = ref(false);
                const selectedGoods = ref([]); // 选中的货品（用于批量添加）

                // 货品搜索 & 分页
                const goodsSearchKey = ref('');
                const goodsCurrentPage = ref(1);
                const goodsPageSize = ref(10);
                const originalGoodsData = ref([]); // 始终保存完整原始数据
                const filteredGoodsData = ref([]); // 保存过滤后的数据（用于分页）
                const goodsTotal = ref(0); // 原始数据总条数
                const paginatedGoodsData = ref([]); // 分页后的数据

                // 明细表格数据
                const goodsDetailData = ref([]); // 最终显示的明细
                const detailIndex = ref(1); // 明细序号

                // 合计数据
                const totalCategories = ref(0); // 调拨种类
                const totalTransferQty = ref(0); // 调拨数量合计
                const totalTransferAmount = ref(0); // 调拨金额合计

                const loadGoodsData = async (outStockId, inStockId) => {
                    try {
                        const res = await axios.get(`/WhTransfer/GetTranceferInfo?outStockId=${outStockId}&inStockId=${inStockId}`);
                        // 强制校验返回数据格式
                        if (!Array.isArray(res.data)) {
                            ElMessage.error('接口返回数据格式错误，需为数组');
                            return;
                        }
                        // 校验关键字段存在
                        const validData = res.data.filter(item =>
                            item.goodsId !== undefined &&
                            item.goodsCode !== undefined &&
                            item.goodsName !== undefined
                        );
                        originalGoodsData.value = validData;
                        filteredGoodsData.value = [...validData];
                        goodsTotal.value = validData.length;
                        handleGoodsPageChange(1);
                        if (validData.length === 0) {
                            ElMessage.info('当前仓库下暂无可调拨的货品（或数据字段缺失）');
                        }
                    } catch (error) {
                        ElMessage.error('加载货品数据失败，请重试');
                        originalGoodsData.value = [];
                        filteredGoodsData.value = [];
                        paginatedGoodsData.value = [];
                    }
                };

                // 分页切换
                const handleGoodsPageChange = (page) => {
                    goodsCurrentPage.value = page;
                    const start = (page - 1) * goodsPageSize.value;
                    const end = start + goodsPageSize.value;
                    // 从过滤后的数据中分页
                    paginatedGoodsData.value = filteredGoodsData.value.slice(start, end) || [];
                };

                // 页大小切换
                const handleGoodsPageSizeChange = (size) => {
                    goodsPageSize.value = size;
                    handleGoodsPageChange(1);
                };

                // 货品搜索
                // const searchGoods = () => {
                //     const filterKey = goodsSearchKey.value.trim().toLowerCase();
                //     基于原始数据生成过滤结果
                //     filteredGoodsData.value = originalGoodsData.value.filter(item =>
                //         item.goodsCode?.toLowerCase().includes(filterKey) ||
                //         item.goodsName?.toLowerCase().includes(filterKey)
                //     );
                //     分页基于过滤后的数据
                //     handleGoodsPageChange(1);
                // };

                // 搜索重置
                // const resetGoodsSearch = () => {
                //     goodsSearchKey.value = '';
                //     filteredGoodsData.value = [...originalGoodsData.value]; 恢复过滤数据为原始数据
                //     handleGoodsPageChange(1);
                // };

                // 表格选中事件
                const handleGoodsSelectionChange = (val) => {
                    selectedGoods.value = val;
                };

                const calculateSummary = () => {
                  totalCategories.value = goodsDetailData.value.length;
                  totalTransferQty.value = goodsDetailData.value.reduce((sum, item) => sum + item.transferQty, 0);
                  totalTransferAmount.value = goodsDetailData.value.reduce((sum, item) => sum + item.transferAmount, 0);
                };
                        
                // 确认添加
                const confirmAddGoods = async () => {
                    if (selectedGoods.value.length === 0) {
                        ElMessage.warning('请选择至少一条货品数据');
                        return;
                    }

                    const newRows = selectedGoods.value.map(item => ({
                        id: detailIndex.value++,
                        goodsId: item.goodsId || '',
                        goodsCode: item.goodsCode || '未知编号',
                        goodsName: item.goodsName || '未知名称',
                        specification: item.specification || '',
                        goodsTypeName: item.goodsTypeName || '未分类',
                        unit: '吨',
                        inStock: item.inStock || 0,
                        outStock: item.outStock || 0,
                        inLocationId: '',  // 明细行的调入库位ID
                        outLocationId: '', // 明细行的调出库位ID
                        transferQty: 1,
                        purchaseReferencePrice: item.purchaseReferencePrice || 0,
                        transferAmount: 1 * (item.purchaseReferencePrice || 0),
                        remark: ''
                    }));

                    goodsDetailData.value = [...goodsDetailData.value, ...newRows];
                    await nextTick();
                    selectedGoods.value = [];
                    addGoodsDialog.value = false;
                    calculateSummary();
                };

                // 监听明细数据变化，自动重新计算合计
                watch(goodsDetailData, () => {
                    calculateSummary();
                });

                // 调拨数量变化时，重新计算金额和合计
                const handleQtyChange = async (row) => {
                    let newRow = { ...row };
                    newRow.transferAmount = newRow.transferQty * newRow.purchaseReferencePrice;

                    // 定义库存下限为5
                    const stockLowerLimit = 5;

                    // 校验调拨数量>调出仓库当前库存
                    if (newRow.transferQty > row.outStock) {
                        try {
                            const confirm = await ElMessageBox.confirm(
                                `调拨数量超过调出仓库当前库存（当前库存：${row.outStock}）`,
                                '库存不足提示',
                                {
                                    confirmButtonText: '确定',
                                    showCancelButton: false,
                                    type: 'warning'
                                }
                            );
                            if (confirm === 'confirm') {
                                // 用户点击确定，将数量改为1
                                newRow.transferQty = 1;
                                newRow.transferAmount = newRow.transferQty * newRow.purchaseReferencePrice;
                            } else {
                                // 用户点击取消，将数量重置为0
                                newRow.transferQty = 0;
                                newRow.transferAmount = 0;
                            }
                        } catch (error) {
                            // 点击取消或关闭弹窗时，同样重置为0
                            newRow.transferQty = 0;
                            newRow.transferAmount = 0;
                        }
                    }
                    // 校验调拨数量>=调出仓库当前库存 - 5 且 小于调出仓库当前库存
                    else if (newRow.transferQty >= (row.outStock - stockLowerLimit) && newRow.transferQty < row.outStock) {
                        try {
                            const confirm = await ElMessageBox.confirm(
                                '当前操作库存将低于货品库存下限，是否执行调拨？',
                                '提示',
                                {
                                    confirmButtonText: '确定',
                                    cancelButtonText: '取消',
                                    type: 'warning'
                                }
                            );
                            if (confirm === 'cancel') {
                                newRow.transferQty = 0; // 点击取消，数量归0
                                newRow.transferAmount = newRow.transferQty * newRow.purchaseReferencePrice;
                            }
                            // 点击确认，数量不变
                        } catch (error) {
                            newRow.transferQty = 0;
                            newRow.transferAmount = newRow.transferQty * newRow.purchaseReferencePrice;
                        }
                    }

                    const index = goodsDetailData.value.findIndex(item => item.id === row.id);
                    if (index > -1) {
                        goodsDetailData.value.splice(index, 1, newRow);
                    }
                    calculateSummary();
                };

                // 单条移除
                const removeDetail = (row) => {
                    const index = goodsDetailData.value.findIndex(item => item.id === row.id);
                    if (index > -1) {
                        goodsDetailData.value.splice(index, 1);
                        calculateSummary();
                    }
                };

                // 批量移除（可结合表格多选实现）
                const removeGoodsDetail = () => {
                    // 示例：移除选中项（需表格开启多选）
                    // const selected = tableRef.value.selection;
                    // 这里简单实现按 id 过滤
                    goodsDetailData.value = goodsDetailData.value.filter(item => !selectedGoods.value.some(s => s.id === item.id));
                    calculateSummary();
                };


                //-----------------------------------仓库与库位（修改后：区分调入/调出）----------------------------------------
                // 1. 调入仓库相关：库位列表 + 选中ID
                const inLocationList = ref([]); // 调入仓库的库位列表
                const selectedInLocationId = ref(''); // 全局选中的调入库位ID（可选，用于快速赋值）

                // 2. 调出仓库相关：库位列表 + 选中ID
                const outLocationList = ref([]); // 调出仓库的库位列表
                const selectedOutLocationId = ref(''); // 全局选中的调出库位ID（可选，用于快速赋值）

                // 3. 监听【调入仓库】变化，加载对应库位
                watch(inWarehouseId, async (newVal) => {
                    // 清空调入库位相关数据（切换仓库时重置）
                    inLocationList.value = [];
                    selectedInLocationId.value = '';
                    // 清空明细中所有调入库位（避免旧仓库的库位残留）
                    goodsDetailData.value.forEach(item => item.inLocationId = '');
                    if (!newVal) return; // 无仓库选择时直接返回
                    try {
                        // 调用调入仓库库位接口（需确保后端接口支持按仓库ID查库位）
                        const res = await axios.get(`/WhInbound/SelectWhLocationForInbound?warehouseId=${newVal}`);
                        inLocationList.value = Array.isArray(res.data) ? res.data : [];
                        if (inLocationList.value.length === 0) {
                            ElMessage.info('该调入仓库下暂无库位数据');
                        }
                    } catch (error) {
                        console.error('加载调入库位失败：', error);
                        ElMessage.error('调入库位加载失败，请重试');
                    }
                });

                // 4. 监听【调出仓库】变化，加载对应库位
                watch(outWarehouseId, async (newVal) => {
                    goodsDetailData.value = [];

                    outLocationList.value = [];
                    selectedOutLocationId.value = '';
                    goodsDetailData.value.forEach(item => item.outLocationId = '');

                    if (!newVal) return;
                    try {
                        const res = await axios.get(`/WhInbound/SelectWhLocationForInbound?warehouseId=${newVal}`);
                        outLocationList.value = Array.isArray(res.data) ? res.data : [];
                        if (outLocationList.value.length === 0) {
                            ElMessage.info('该调出仓库下暂无库位数据');
                        }
                        ElMessage.info('调出仓库信息发生变更，明细已清空');
                    } catch (error) {
                        console.error('加载调出库位失败：', error);
                        ElMessage.error('调出库位加载失败，请重试');
                    }
                });

                // 5. 库位下拉框点击提示（区分调入/调出，可选）
                const handleInLocationClick = () => {
                    if (!inWarehouseId.value) {
                        ElMessage.warning('请先选择【调入仓库】，再选择库位');
                    }
                };
                const handleOutLocationClick = () => {
                    if (!outWarehouseId.value) {
                        ElMessage.warning('请先选择【调出仓库】，再选择库位');
                    }
                };

                const outLocationAqty = ref('');

                const handleOutLocationChange = async (row) => {
                    try {
                        const res = await axios.get(
                            `/WhTransfer/GetAvailableInventoryQty?locationId=${row.outLocationId}&warehouseId=${outWarehouseId.value}&goodsId=${row.goodsId}`
                        );
                        const stock = res.data;

                        if (stock < 5) {
                            const rowIndex = goodsDetailData.value.findIndex(item => item.id === row.id);
                            if (rowIndex > -1) {
                                const updatedRow = { ...row };
                                updatedRow.outLocationId = '';
                                updatedRow.outLocationAqty = '';
                                goodsDetailData.value.splice(rowIndex, 1, updatedRow);
                            }
                            ElMessage.warning('当前库位库存不足，不允许出库');
                            return;
                        }

                        row.outLocationAqty = stock;
                    } catch (error) {
                        console.error('加载调出库存失败：', error);
                        ElMessage.error('加载调出库存失败，请重试');
                    }
                };



                //-----------------------------------仓库与库位（修改结束）----------------------------------------

                //-----------------------------------调拨明细结束--------------------------------------

                //-----------------------------------保存----------------------------------------------------------

                const saveThis = async () => {
                    // 1. 校验当前用户ID是否有效
                    if (!currentUserId.value || currentUserId.value === '') {
                        ElMessage.error('未检测到有效登录信息，请重新登录');
                        return;
                    }

                    // 2. 基础校验（必填项）
                    if (!transferOrderNo.value || !inWarehouseId.value || !outWarehouseId.value || !purchaseDate.value ){
                        ElMessage.warning('请完善调拨单号、调入/调出仓库等必填信息');
                        return;
                    }
                    if (goodsDetailData.value.length === 0) {
                        ElMessage.warning('请至少添加一条调拨明细');
                        return;
                    }
                    if (isSaveBtnDisabled.value) return;
                    let hasEmptyLocation = false;
                    goodsDetailData.value.forEach(row => {
                        if (!row.inLocationId || !row.outLocationId) {
                            hasEmptyLocation = true;
                        }
                    });
                    if (hasEmptyLocation) {
                        ElMessage.warning('所有调拨明细必须选择【调入仓库位】和【调出仓库位】！');
                        return; // 阻止提交
                    }

                    let hasInvalidQty = false;
                    let hasQtyOne = false;
                    goodsDetailData.value.forEach(row => {
                        const qty = row.transferQty;
                        if (qty <= 0) {
                            hasInvalidQty = true;
                        } else if (qty > 0 && qty < 2) {
                            hasQtyOne = true;
                        }
                    });
                    if (hasInvalidQty) {
                        ElMessage.error('存在调拨数量不正确的明细');
                        return;
                    }
                    if (hasQtyOne) {
                        try {
                            const confirmRes = await ElMessageBox.confirm(
                                '当前存在调拨数量为1的明细，您确定进行调拨吗？',
                                '提示',
                                {
                                    confirmButtonText: '确定',
                                    cancelButtonText: '取消',
                                    type: 'warning'
                                }
                            );
                            if (confirmRes === 'cancel') {
                                ElMessage.info('已取消调拨操作');
                                return;
                            }
                        } catch (error) {
                            ElMessage.info('已取消调拨操作');
                            return;
                        }
                    }
                    
                    // -------------------------- 新增：生成所有附件共用的公共编码 --------------------------
                    // 规则：调拨单号 + 下划线 + GUID（确保唯一且与当前调拨单强关联）
                    const commonAttachmentCode = `${transferOrderNo.value}_${self.crypto.randomUUID()}`;
                    // -------------------------------------------------------------------------------------

                    // 3. 收集已上传附件的【服务器文件路径】（用于提交失败回滚）
                    const attachmentServerPaths = tempFileList.value
                        .filter(file => file.serverFilePath)
                        .map(file => file.serverFilePath);

                    try {
                        // 4. 构造提交数据（所有附件的 AttachmentCode 赋值为 commonAttachmentCode）
                        const submitData = {
                            wtmwm: { // 主表数据（不变）
                                TransferOrderNo: transferOrderNo.value,
                                TransferType: selectedStockType.value,
                                TransferApplyDate: purchaseDate.value,
                                TransferOutWarehouseId: outWarehouseId.value,
                                TransferWarehouseId: inWarehouseId.value,
                                OperatorBy: selectedUsers.value[0]?.id ? Number(selectedUsers.value[0].id) : 0,
                                Inbound: '未入库',
                                Outbound: '未出库',
                                CreateBy: Number(currentUserId.value),
                                UpdateBy: Number(currentUserId.value)
                            },
                            detailList: goodsDetailData.value.map(item => ({ // 明细数据（不变）
                                GoodsCode: item.goodsCode,
                                GoodsTypeId: item.goodsTypeId || 0,
                                ProductUnit: item.unit,
                                TransferQuantity: item.transferQty,
                                TransferUnitPrice: item.purchaseReferencePrice,
                                FromLocation: item.outLocationId ? Number(item.outLocationId) : 0,
                                ToLocation: item.inLocationId ? Number(item.inLocationId) : 0,
                                InboundNum: item.transferQty || 0,
                                OutboundNum: item.transferQty || 0,
                                // 明细关联附件：存储公共编码（便于后续查询该调拨单的所有附件）
                                AttachmentCode: commonAttachmentCode,
                                Remarks: item.remark || '',
                                CreateBy: Number(currentUserId.value),
                                UpdateBy: Number(currentUserId.value)
                            })),
                            attachmentList: tempFileList.value.map(file => ({ // 附件数据（关键修改）
                                // 所有附件的 AttachmentCode 统一为 commonAttachmentCode
                                AttachmentCode: commonAttachmentCode,
                                AttachmentAddress: file.serverFilePath || '',
                                CreateBy: currentUserId.value,
                                UpdateBy: currentUserId.value,
                                CreateTime: new Date(),
                                UpdateTime: new Date()
                            }))
                        };

                        // 5. 调用后端提交接口（不变）
                        const res = await axios.post(
                            '/WhTransfer/AddTransferAndDetailWithAttachment',
                            submitData,
                            { headers: { 'Content-Type': 'application/json' } }
                        );

                        // 6. 提交成功处理（不变）
                        if (res.data > 0) {
                            ElMessage.success('调拨单保存成功');
                            isSaveBtnDisabled.value = true;
                            axios.post('/NumberingRules/GenerateAndUpdateNumber?ruleId=5')
                            .then(res=>{
                                setTimeout(() => window.location.href = '/WhTransfer/Index', 500);
                            })
                            closeDetail();
                            setTimeout(() => {
                                isSaveBtnDisabled.value = false;
                            }, 3000);
                        } else {
                            throw new Error(res.data.message || '服务器返回提交失败');
                        }
                    } catch (error) {
                        // 7. 提交失败回滚（不变）
                        console.error('调拨单提交失败：', error);
                        ElMessage.error(`保存失败：${error.message || '网络异常'}`);

                        if (attachmentServerPaths.length > 0) {
                            try {
                                await axios.post(
                                    '/WhTransfer/DeleteAttachmentByPath',
                                    attachmentServerPaths,
                                    { headers: { 'Content-Type': 'application/json' } }
                                );
                                ElMessage.info('已自动删除服务器上的临时附件');
                                tempFileList.value = [];
                            } catch (rollbackError) {
                                console.error('附件回滚删除失败：', rollbackError);
                                ElMessage.warning('服务器附件删除失败，请手动清理');
                            }
                        }
                    }
                };


                //-----------------------------------保存结束------------------------------------------------------

    
                // -------------------------- 4. 未定义函数设为空函数 --------------------------
                const handleDateChange = () => {}; // 日期变化
                const handleWarehouseChange = () => {}; // 仓库变化
                const handleSelectionChange = () => {}; // 货品表格选中
                const formatNumber = (row, column, cellValue) => {
                    // 处理空值、undefined 或非数字，返回 0.00
                    if (cellValue === null || cellValue === undefined || isNaN(Number(cellValue))) {
                        return '0.00';
                    }
                    // 保留两位小数，支持千位分隔符（如 1,234.56）
                    return Number(cellValue).toLocaleString('zh-CN', {
                        minimumFractionDigits: 2,
                        maximumFractionDigits: 2
                    });
                };
                const closeDetail = () => {
                    window.location.href="/WhTransfer/Index";
                }; // 页面关闭
                const saveAsDraft = () => {}; // 保存草稿
    
                // -------------------------- 5. 页面初始化 --------------------------
                onMounted(async () => {
                    initDictData();
                    getTransferOrder();
                    await loadFilterDepartments();
                    await loadFilterPersons();
                    await loadWarehouseList();
                });
    
                // -------------------------- 6. 返回所有模板引用的变量/方法 --------------------------
                return {
                    // 数据字典、经办人选择等基础相关
                    stockInTypeList,
                    selectedStockType,
                    selectOperatorModel,
                    operatorName,
                    filterDepartTree,
                    filteredUsers,
                    selectedUsers,
                    currentUserId,
                    isSaveBtnDisabled,

                    // 仓库相关
                    inWarehouseId,
                    outWarehouseId,
                    handleAddGoods,
                    checkWarehouseSame,
                    warehouseList,
                    handleInLocationClick,
                    handleOutLocationClick,
                    outLocationList,
                    inLocationList,
                    handleOutLocationChange,
                    outLocationAqty,

                    // 调拨明细、弹窗、分页等相关
                    addGoodsDialog,
                    goodsSearchKey,
                    goodsCurrentPage,
                    goodsPageSize,
                    goodsTotal,
                    originalGoodsData,
                    paginatedGoodsData,
                    selectedGoods,
                    detailIndex,
                    totalCategories,
                    totalTransferQty,
                    totalTransferAmount,
                    loadGoodsData,
                    handleGoodsPageChange,
                    handleGoodsPageSizeChange,
                    // searchGoods,
                    // resetGoodsSearch,
                    handleGoodsSelectionChange,
                    confirmAddGoods,
                    calculateSummary,
                    handleQtyChange,
                    removeDetail,
                    removeGoodsDetail,
                    goodsTableRef,

                    // 上传附件相关
                    tempFileList,
                    handleFileExceed,
                    handleUploadSuccess,
                    removeTempFile,
                    handleFileRemove,

                    // 其他基础变量和空函数（按实际模板使用情况，若模板用到就保留返回）
                    transferOrderNo,
                    purchaseDate,
                    selectedWarehouseId,
                    remark,
                    nonPurchaseQuantity,
                    receivedQuantity,
                    handleDateChange,
                    handleWarehouseChange,
                    handleSelectionChange,
                    formatNumber,
                    closeDetail,
                    saveAsDraft,
                    saveThis,

                    // 单号、部门人员加载等方法
                    initDictData,
                    getTransferOrder,
                    loadFilterDepartments,
                    loadFilterPersons,
                    getDeptIdsRecursive,
                    handleOrgSelect,
                    handleUserSelect,
                    removeSelectedUser,
                    confirmOperatorSelect,
                    openAddGoodsDialog,
                    handleDetailSelectAll,
                    handleDetailSelectionChange,
                    goodsDetailData,
                    isSaveBtnDisabled,
                };
            }
        });
        app.use(ElementPlus, {
            locale: ElementPlusLocaleZhCn
        });
        app.mount('#app');
    </script>
</body>
</html>